package com.feidee.data.report.dao.impl;

import com.feidee.data.report.constant.Constant;
import com.feidee.data.report.dao.IFunnelAnalyseDao;
import com.feidee.data.report.exception.DataDaoException;
import com.feidee.data.report.model.FunnelLogModel;
import com.feidee.data.report.model.FunnelResult;
import com.feidee.data.report.util.JdbcManager;
import com.feidee.data.report.util.ToolUtils;
import com.feidee.fdcommon.configuration.CustomConfiguration;
import com.feidee.fdhadoop.logCollect.LogCollectService;
import org.apache.log4j.Logger;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public class FunnelAnalyseDaoImpl implements IFunnelAnalyseDao {

	public Logger logger = Logger.getLogger(FunnelAnalyseDaoImpl.class);

	private DataSource clickhouseDataSource1;
	private DataSource clickhouseDataSource2;
	private DataSource clickhouseDataSource3;
	private DataSource clickhouseDataSource4;
	private DataSource clickhouseDataSource5;
	private DataSource clickhouseDataSource6;
	private DataSource clickhouseDataSource7;
	private DataSource clickhouseDataSource8;
	private DataSource clickhouseDataSource9;
	private DataSource clickhouseDataSource10;
	private DataSource clickhouseDataSource11;
	private DataSource clickhouseDataSource12;
	private DataSource clickhouseDataSource13;

	@Override
	public List<FunnelResult> runSql(String request_id, String searchSql, int eventNum, int databaseNum) {
		List<FunnelResult> funnelResultList = new ArrayList<>();
		DataSource dataSource = getDataSource(databaseNum);
		Connection connection = null;
		Statement statement = null;
		ResultSet resultSet = null;
		FunnelLogModel funnelLogModel = new FunnelLogModel();
		try {
			funnelLogModel.setRequest_id(request_id);
			funnelLogModel.setDatabase_id(String.valueOf(databaseNum));
			funnelLogModel.setSql_content(searchSql);
			long startTime = System.currentTimeMillis();
			funnelLogModel.setStart_time(ToolUtils.getTimeStr(startTime));
			connection = dataSource.getConnection();
			statement = connection.createStatement();
			resultSet = statement.executeQuery(searchSql);
			funnelLogModel.setCost_time(String.valueOf((System.currentTimeMillis() - startTime) / 1000.0));
			ResultSetMetaData rsm = resultSet.getMetaData();
			int columnCount = rsm.getColumnCount();
			if (resultSet.next()) {
				for (int i = 1; i <= columnCount; i++) {
					String columnName = "event_" + i;
					String value = resultSet.getString(columnName);
					FunnelResult funnelResult = new FunnelResult();
					funnelResult.setIndex(String.valueOf(i));
					funnelResult.setNum(value);
					funnelResultList.add(funnelResult);
				}
			} else {
				// clickhouse查询如果没任何结果resultSet为0行，需初始化结果集为0
				for (int i = 1; i <= eventNum; i++) {
					FunnelResult funnelResult = new FunnelResult(String.valueOf(i), "0");
					funnelResultList.add(funnelResult);
				}
			}
			logger.info("漏斗分析查询ID: " + request_id + " 在 " + databaseNum + " 号数据库获取结果集为: " + funnelResultList.toString());
			funnelLogModel.setStatus("1");
		} catch (SQLException e) {
			logger.error("漏斗分析查询SQL: " + searchSql + " 获取结果异常", e);
			funnelLogModel.setStatus("0");
			return null;
		} finally {
			try {
				LogCollectService.sendLog(CustomConfiguration.getString(Constant.LOG_APT),
						CustomConfiguration.getString(Constant.FUNNEL_LOG_BUS), funnelLogModel);
				JdbcManager.destroy(connection, statement, resultSet);
			} catch (DataDaoException e) {
				logger.error("关闭clickhouse连接失败");
			}
		}
		return funnelResultList;
	}

	private DataSource getDataSource(int databaseNum) {
		if (databaseNum == 1) {
			return clickhouseDataSource1;
		} else if (databaseNum == 2) {
			return clickhouseDataSource2;
		} else if (databaseNum == 3) {
			return clickhouseDataSource3;
		} else if (databaseNum == 4) {
			return clickhouseDataSource4;
		} else if (databaseNum == 5) {
			return clickhouseDataSource5;
		} else if (databaseNum == 6) {
			return clickhouseDataSource6;
		} else if (databaseNum == 7) {
			return clickhouseDataSource7;
		} else if (databaseNum == 8) {
			return clickhouseDataSource8;
		} else if (databaseNum == 9) {
			return clickhouseDataSource9;
		} else if (databaseNum == 10) {
			return clickhouseDataSource10;
		} else if (databaseNum == 11) {
			return clickhouseDataSource11;
		} else if (databaseNum == 12) {
			return clickhouseDataSource12;
		} else if (databaseNum == 13) {
			return clickhouseDataSource13;
		}
		return null;
	}

	public void setClickhouseDataSource1(DataSource clickhouseDataSource1) {
		this.clickhouseDataSource1 = clickhouseDataSource1;
	}

	public void setClickhouseDataSource2(DataSource clickhouseDataSource2) {
		this.clickhouseDataSource2 = clickhouseDataSource2;
	}

	public void setClickhouseDataSource3(DataSource clickhouseDataSource3) {
		this.clickhouseDataSource3 = clickhouseDataSource3;
	}

	public void setClickhouseDataSource4(DataSource clickhouseDataSource4) {
		this.clickhouseDataSource4 = clickhouseDataSource4;
	}

	public void setClickhouseDataSource5(DataSource clickhouseDataSource5) {
		this.clickhouseDataSource5 = clickhouseDataSource5;
	}

	public void setClickhouseDataSource6(DataSource clickhouseDataSource6) {
		this.clickhouseDataSource6 = clickhouseDataSource6;
	}

	public void setClickhouseDataSource7(DataSource clickhouseDataSource7) {
		this.clickhouseDataSource7 = clickhouseDataSource7;
	}

	public void setClickhouseDataSource8(DataSource clickhouseDataSource8) {
		this.clickhouseDataSource8 = clickhouseDataSource8;
	}

	public void setClickhouseDataSource9(DataSource clickhouseDataSource9) {
		this.clickhouseDataSource9 = clickhouseDataSource9;
	}

	public void setClickhouseDataSource10(DataSource clickhouseDataSource10) {
		this.clickhouseDataSource10 = clickhouseDataSource10;
	}

	public void setClickhouseDataSource11(DataSource clickhouseDataSource11) {
		this.clickhouseDataSource11 = clickhouseDataSource11;
	}

	public void setClickhouseDataSource12(DataSource clickhouseDataSource12) {
		this.clickhouseDataSource12 = clickhouseDataSource12;
	}

	public void setClickhouseDataSource13(DataSource clickhouseDataSource13) {
		this.clickhouseDataSource13 = clickhouseDataSource13;
	}
}
